/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module appl.c - Application Idle Engine hook functions |
   @end

$Log: /SoftPay/SPK2SIM/Source/Main/appl.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#include <project.h>

//#include <beetle.h>
//#include <beetleplug.h>

#include <aclconio.h>
#include <aclstr.h>
#include <svctxo.h>
#include <applidl.h>
#include <message.h>
#include <applidl.h>
#include <svc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <prot8583.h>
#include <acldev.h>
#include <power.h>

#ifdef DEBUG_VSAPPL
#define DEBUG_95
#endif

#include <define.h>
#include <appl.h>
#include <init.h>
#include <msg.h>
#include <msgfuncs.h>
#include <spdebug.h>
#include <gds.h>
#include <init.h>
#include <oper.h>
#include <operate.h>
#include <date.h>
#include <menufunc.h>
#include <mdlfuncs.h>
#include <card.h>
#include <settle.h>
#include <format.h>
#include <stats.h>
#include <form.h>
#include <piputl.h>
#include <ifldtbl.h>
#include <isoutl.h>
#include <iso8msg.h>

#ifdef PROCESS8583_DEFINED
#include <packet.h>
#include <isosizes.h>
#include <iso8utl.h>
#endif


#include <ui.h>
#include <logo.h>
#include <hdt.h>
#include <tct.h>
#include <codesec.h>

#include <stats.h>
#ifdef FHANDLE
#undef FHANDLE 
#endif

#include <varrec.h>
#include <eeslapi.h>
#include <logsys.h>
#include <mamevent.h>
#include <vmac.h>
#include <confproto.h>
//#include <tma.h>   PREDATOR

#include "..\..\hostsrc\imamsrc\imamsrc.h"
extern unsigned long lnBackLightTimer;

#define    DISPLAY_DATE    1
#define    DISPLAY_TITLE   2

int inNoDisp;                   /* do not display clock time */
long lnEventMap;
unsigned int gu_clr_state;
char arabic ;
static int inX1Cord,
inY1Cord,
inX2Cord,
inY2Cord;

static int inMultiAppFlag;

/* Bruce_g1 - MAM integration GLOBALS */
byte bEESLList[sizeof(EESL_IMM_DATA) * 30];
int inMAMAvailable = 0;
EESL_CONTROL_STR* psrEESLGlobalDataSpace;
int hConsoleS;
short shInputEvent = 0;

/* End of MAM globals */

extern void vdPrintDebugLog(void);

/*-------------------------------------------------------------------------
    Function:       Main
    Description:    Application main - start
    Parameters:
    Returns:        VS_TRUE
    Notes:          BT_Start is the Beetle hook
--------------------------------------------------------------------------*/

int main(int argc, char* argv[])
{
	int 				inReturnValue = 0;
	long 			lnEESLAPIReturnValue = 0;
	unsigned short	ushEvent = 0;

	LOG_INIT("SOFTPAY", LOGSYS_COMM, 0xFFFFFFFF);
	LOG_PRINTFF((EESL_DEBUG_GLOBAL, "SOFTPAY - Entered main()"));

	psrEESLGlobalDataSpace = (EESL_CONTROL_STR*)calloc(sizeof(EESL_CONTROL_STR), 1);
	
	if (!psrEESLGlobalDataSpace)
	{
		LOG_PRINTFF((EESL_DEBUG_GLOBAL, "calloc(EESL_CONTROL_STR) failed"));

		error_tone();
		exit(1);
	}
	
	lnEESLAPIReturnValue = EESL_Initialise(argv, argc, "SOFTPAY", psrEESLGlobalDataSpace);

	if(lnEESLAPIReturnValue == 0)
	{
		LOG_PRINTFF((EESL_DEBUG_GLOBAL, "SOFTPAY registration SUCCESS"));
		inMAMAvailable = 1;
	}
	else
	{
		LOG_PRINTFF((EESL_DEBUG_GLOBAL, "SOFTPAY registration FAILED"));
		inMAMAvailable = 0;

		if (psrEESLGlobalDataSpace)
		{
			free(psrEESLGlobalDataSpace);
			psrEESLGlobalDataSpace = NULL;
		}
	}

	inReturnValue = terminal_coldboot();
	
	if (inReturnValue != TRUE)
	{
		LOG_PRINTFF((EESL_DEBUG_GLOBAL, "terminal_coldboot() failed"));
		
		error_tone();
		exit(1);
	}

	INCREMENT_REBOOT_COUNT;

	#ifdef BEETLE
		BT_Start();
	#endif

	wherewin(&inX1Cord, &inY1Cord, &inX2Cord, &inY2Cord);

	// JTB The following represent calls to ACT2000 to set up global pointers,
	// data, etc.  This is required when using ACT2000 as a shared library.

	#ifdef PIP_DEFINED

		tdst_8583 = dst_8583buf;
		tsrc_8583 = src_8583buf;
		iso8583_main(convert_table, return_variant1, return_variant2, tdst_8583, tsrc_8583);
		prot8583_main((RevFxn) inUpdateReversal);


	#ifdef __arm    
		pip_main(stMap8583, (char *) Mti, szPIPProcCode, (PFI_INT_SH) tset_trans_fields);
	#else
		pip_main(stMap8583, (char *) Mti, szPIPProcCode, (PFI_INT_INT) tset_trans_fields);
	#endif 

	#endif

	#ifdef ISO8583_DEFINED

		pchDst8583Buf = ucDst8583Buf;
		pchSrc8583Buf = ucSrc8583Buf;

	#ifdef PROCESS8583_DEFINED
		ISO8583_main(ISO8583convert_table, ISO8583return_variant1, ISO8583return_variant2, pchDst8583Buf, pchSrc8583Buf);
	#else
		iso8583_main(ISO8583convert_table, ISO8583return_variant1, ISO8583return_variant2, pchDst8583Buf, pchSrc8583Buf);
	#endif

	#endif
	LOG_PRINTFF((0x08L, "IN_APPL_COLD_INIT..."));
	inApplColdInit();                /* Open Devices and get logon */
	vdFlushCardBuffer();         /* Clean out card buff        */


	/* MAM ADDITION: If MAM is active, then initialization is now complete */
	/* We can now close all the devices, and hand control back to MAM      */
	/***********************************************************************/
	
	if (inMAMAvailable)
	{
		LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Releasing devices"));

		/* This was the input event */
		ushEvent = shInputEvent;

		inAppl_deactivate();

		vdPrintDebugLog();
		
		close(hConsoleS) ;
		SVC_WAIT(500);
		LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Closed the console %d", hConsoleS));

		vdPrintDebugLog();

		lnEESLAPIReturnValue = EESL_send_event("DEVMAN", RES_COMPLETE_EVENT, (unsigned char*)&ushEvent, sizeof(ushEvent));
		while (lnEESLAPIReturnValue != 0)
		{
			SVC_WAIT(200);
			lnEESLAPIReturnValue = EESL_send_event("DEVMAN", RES_COMPLETE_EVENT, (unsigned char*)&ushEvent, sizeof(ushEvent));
		}

		aie_main(idle_table, appl_table, appl_idle_loop, fast_poll, slow_poll, inAppl_activate, inAppl_deactivate);
	}
	else
	{
		LOG_PRINTFF((0x08L, "BEFORE AIEMAIN: IMAM_INIT_UCL"));
		inImamInitUclCommEx(); 
		//	inimamsetEthernet();

		srGDS.ulIdleTimerCount = set_itimeout(NO_CLOCK_HANDLE inGetIdleTimeOut(), TM_SECONDS);
		srGDS.ulIdleTimerCount = srGDS.ulIdleTimerCount + (lnBackLightTimer-120000L);  
		aie_main(idle_table, appl_table, appl_idle_loop, fast_poll, slow_poll, inAppl_activate, inAppl_deactivate);
	}

	return VS_TRUE;
}


/*-------------------------------------------------------------------------
    Function:       appl_coldboot
    Description:    hook function to AIE
    Parameters:
    Returns:        VS_TRUE
    Notes:          BT_Start is the Beetle hook
--------------------------------------------------------------------------*/
int appl_coldboot() {
    wherewin(&inX1Cord, &inY1Cord, &inX2Cord, &inY2Cord);
    inApplColdInit();                /* Open Devices and get logon */
    vdFlushCardBuffer();                /* Clean out card buff        */

    BT_Start();

    /* -- ba1: increment the reboot counter -- */
    INCREMENT_REBOOT_COUNT;

    return(VS_TRUE);
}

/*-------------------------------------------------------------------------
    Function:       appl_idle_loop
    Description:    Called by Application Idle Engine every branch and once
                    per idle cycle
    Parameters:
    Returns:        VS_TRUE
    Notes:
--------------------------------------------------------------------------*/

short appl_idle_loop() {
    TRANSACTION_OBJECT obTran,
    * pobTran;
    memset(&obTran, 0x00, sizeof(TRANSACTION_OBJECT));
    pobTran = &obTran;

    gu_clr_state = 0;    /* clear key hasn't been pressed */

    inRunOperation(pobTran, IDLE_LOOP_OPERATION);

    return(BRANCH_EXIT);
}


short terminal_coldboot()
{	
	event_t lnEvent;

	int inTimer = 0;
	int inEESLAPIReturnValue = 0;
	 //jrd one source
       #ifdef __arm
       unsigned short ushEventDataSize = 0;
       #endif
       #ifdef _TARG_68000
       unsigned int ushEventDataSize = 0;
       #endif
	unsigned short ushEESLAPIReturnValue = 0;
	
	VS_BOOL fExitCondition = VS_FALSE;

	char szBuffer[8];
	char szLogicalName[16];
	unsigned char szEventDataBuffer[512];

	if (!inMAMAvailable)
	{
		inMultiAppFlag = FALSE;
		
		if (get_env("#MLAPP", szBuffer, 1) > 0)
		{
			inMultiAppFlag = TRUE;
			
			if (get_console(0) == -1)
				lnEventMap = wait_event();
		}
		else	
		{
			// Shared library version must open console

			vdPrintDebugLog();
			
			hConsoleS = open(DEV_CONSOLE, 0);
			LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Opening the console : %d", hConsoleS));

			vdPrintDebugLog();
			
			return (hConsoleS < 0) ? FALSE : TRUE;
		}
	}
	else
	{
		inEESLAPIReturnValue = EESL_queue_count();
		LOG_PRINTFF((EESL_DEBUG_GLOBAL, "1. EESL Queue Count = %d", inEESLAPIReturnValue));
		
		if (inEESLAPIReturnValue == 0)
		{
			inTimer = set_timer(4000L, EVT_TIMER);

			lnEvent = 0;
			while ((EESL_queue_count() == 0) && ((lnEvent & EVT_TIMER) == 0))
			{
				lnEvent = wait_event();
			}

			clr_timer(inTimer);

			// VMAC behavior is as follows:
			// 
			// If SOFTPAY is the only application on the terminal then the FRONTEND sends an ACT_EVENT (ie. defined in SOFTPAY.INS)
			// to SOFTPAY before the 4 second timer triggers. On the other hand if there are multiple applications then SOFTPAY has to
			// take the initiative and send a SOFTPAY_INIT event after waiting for 4 seconds. "Why particularly 4 seconds?", I have no
			// idea.

			if ((lnEvent & EVT_TIMER) != 0)
			{
				/* SOFTPAY IS NOT THE ONLY APPLICATION DISPLAYED BY FRONT END */
				
				LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Sending SOFTPAY_INIT"));
				
				inEESLAPIReturnValue = EESL_send_event("DEVMAN", SOFTPAY_INIT, NULL, 0);
				
				while (inEESLAPIReturnValue != 0)
				{
					SVC_WAIT(200);
					inEESLAPIReturnValue = EESL_send_event("DEVMAN", SOFTPAY_INIT, NULL, 0);
				}

				/* Store this for when we do res-complete */
				shInputEvent = SOFTPAY_INIT;

				/* Wait for a PIPE event */

				memset(szLogicalName, 0x00, sizeof(szLogicalName));
				memset(szEventDataBuffer, 0x00, sizeof(szEventDataBuffer));

				while (!fExitCondition)
				{
					LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Waiting for pipe event"));

					inEESLAPIReturnValue = EESL_queue_count();
					LOG_PRINTFF((EESL_DEBUG_GLOBAL, "EESL Queue Count = %d", inEESLAPIReturnValue));
					
					if (inEESLAPIReturnValue == 0)
					{
						while ((lnEvent = wait_event()) != EVT_PIPE)
						{
							SVC_WAIT(0);
						}
					}

					LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Reading custom event"));
					
					/* Should have our initialization custom event */

					inEESLAPIReturnValue = EESL_queue_count();
					LOG_PRINTFF((EESL_DEBUG_GLOBAL, "EESL Queue Count = %d", inEESLAPIReturnValue));
					
					if (inEESLAPIReturnValue != 0)
					{
						ushEESLAPIReturnValue = EESL_read_cust_evt(	szEventDataBuffer, sizeof(szEventDataBuffer), 
																&ushEventDataSize, szLogicalName);

						LOG_PRINTFF((EESL_DEBUG_GLOBAL, "EESL_read_cust_evt() %u %s %u %s",
								ushEESLAPIReturnValue, szEventDataBuffer, ushEventDataSize, szLogicalName));

						/* There should only be ONE custom event sent at this stage */
						
						if (ushEESLAPIReturnValue == SOFTPAY_INIT)
						{
							LOG_PRINTFF((EESL_DEBUG_GLOBAL, "SOFTPAY_INIT received"));

							vdPrintDebugLog();
	
							hConsoleS = open(DEV_CONSOLE, 0);
							LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Opening the console : %d", hConsoleS));

							vdPrintDebugLog();
														
							fExitCondition = VS_TRUE;
						}

						/* If the devices are unavailable, then wait */
						if (ushEESLAPIReturnValue == APP_RES_SET_UNAVAILABLE)
						{
							SVC_WAIT(800);
							LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Retry SOFTPAY_INIT"));

							inEESLAPIReturnValue = EESL_send_event("DEVMAN", SOFTPAY_INIT, NULL, 0);
				
							while (inEESLAPIReturnValue != 0)
							{
								SVC_WAIT(200);
								inEESLAPIReturnValue = EESL_send_event("DEVMAN", SOFTPAY_INIT, NULL, 0);
							}
						}
					}
				}
			} 
			else
			{
				/* THE ONLY EVENT WE COULD HAVE RECEIVED IS THE ACTIVATE EVENT */

				LOG_PRINTFF((EESL_DEBUG_GLOBAL, "ACT_EVENT is pending here"));
				
				ushEESLAPIReturnValue = EESL_read_cust_evt(	szEventDataBuffer, sizeof(szEventDataBuffer), 
														&ushEventDataSize, szLogicalName);

				LOG_PRINTFF((EESL_DEBUG_GLOBAL, "EESL_read_cust_evt() %u %s %u %s",
								ushEESLAPIReturnValue, szEventDataBuffer, ushEventDataSize, szLogicalName));
				
				/* There should only be ONE custom event sent at this stage */
				/* Store this for when we do res-complete */
				
				shInputEvent = ushEESLAPIReturnValue;
				LOG_PRINTFF((EESL_DEBUG_GLOBAL, "shInputEvent = %d", shInputEvent));

				vdPrintDebugLog();

				hConsoleS = open(DEV_CONSOLE, 0);
				LOG_PRINTFF((EESL_DEBUG_GLOBAL, "Opening the console : %d", hConsoleS));

				vdPrintDebugLog();			}
		}
	}

	return TRUE;
}


int inMultiApp(TRANSACTION_OBJECT* pobTran) {
    return (VS_SUCCESS);
}

int APPL_CODE_CHECK(char* a,char* b,short* c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}



